package biolabs.model.division

import biolabs.core.{BioObject, Interaction, WrappedDelegate}
import biolabs.model.PositioningBioContainer
import biolabs.space.ContinuousPosition
import biolabs.space.DiscretePosition
import biolabs.space.GridShapedObject
import biolabs.util.Pair

import scala.collection.JavaConversions._

class Division[
	T <: BioObject with GridShapedObject[P, C] with Divisible[T, P],
	P <: DiscretePosition[P, C],
	C <: ContinuousPosition[C, P]
]
extends Interaction[PositioningBioContainer[T , P], Unit, Unit, DivisionDelegate[P, T], T] {

	/**
	 * Performs the division of contained bio-objects.
	 */
	override def perform(
			parent: PositioningBioContainer[T, P],
			participants: Iterable[WrappedDelegate[DivisionDelegate[P, T], T]],
			notifyProgress: Unit=>Unit
	): Unit = {

		// TODO could be done concurrently for all contained bio-objects
		// with concurrent list implementation of children
		for(dd <- participants) {
			// check that the space requested for the new cell
			// is currently occupied by the parent cell
			var ok = true;
			for(pos <- dd.space) {
				if(parent.getChildAt(pos) ne dd.owner) {
					ok = false;
					// TODO log instead of stderr
					System.err.println("Warning: element " + pos +
							" requested in division, which is outside" +
							" the child object. Division refused.");
					// break; // TODO in Scala 2.8
				}
			}
			if(ok) {
				// assign the required space to the new cell
				val daughter = dd.daughter()
				parent.addChild(daughter, dd.space)

				// notify the parent cell and take ownership of the new cell
				dd.commit();
			}
		}
	}
}